package com.irdstudio.efp.esb.api.service.psd.credit;

import com.alibaba.fastjson.JSON;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.redis.curator.CuratorLock;
import com.irdstudio.efp.basic.framework.mq.client.producer.MQProducerMessageClient;
import com.irdstudio.efp.basic.framework.mq.constant.TagEnums;
import com.irdstudio.efp.basic.framework.mq.constant.TopicEnums;
import com.irdstudio.efp.console.common.ConsoleConstant;
import com.irdstudio.efp.console.common.psd.PsdConstantSet;
import com.irdstudio.efp.console.service.facade.PubSysInfoService;
import com.irdstudio.efp.ctr.service.vo.CtrLoanContVO;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.cus.service.vo.CusIndivVO;
import com.irdstudio.efp.esb.api.bean.psd.credit.req.PsdLimitActivatedReqBean;
import com.irdstudio.efp.esb.api.bean.psd.credit.resp.PsdLimitActivatedRespBean;
import com.irdstudio.efp.esb.api.service.common.repository.CtrLoanRepository;
import com.irdstudio.efp.esb.api.service.common.repository.LmtRepository;
import com.irdstudio.efp.esb.api.service.common.repository.NlsRepository;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.service.bo.req.frontsystem.MobileBankInfoReqBean;
import com.irdstudio.efp.esb.service.bo.req.frontsystem.NetworkBankInfoReqBean;
import com.irdstudio.efp.esb.service.bo.req.traditionalcore.AccountQueryReqBean;
import com.irdstudio.efp.esb.service.bo.resp.frontsystem.MobileBankInfoRespBean;
import com.irdstudio.efp.esb.service.bo.resp.frontsystem.NetworkBankInfoRespBean;
import com.irdstudio.efp.esb.service.bo.resp.traditionalcore.AccountQueryRespBean;
import com.irdstudio.efp.esb.service.facade.EsbInvokeWrapper;
import com.irdstudio.efp.esb.service.facade.frontsystem.MobileBankInfoService;
import com.irdstudio.efp.esb.service.facade.frontsystem.NetworkBankInfoService;
import com.irdstudio.efp.esb.service.facade.tranditionalcore.AccountQueryService;
import com.irdstudio.efp.limit.service.facade.LmtPrdContService;
import com.irdstudio.efp.limit.service.vo.LmtPrdContVO;
import com.irdstudio.efp.nls.common.constant.PrdAdaptedSoltEnums;
import com.irdstudio.efp.nls.service.common.rules.ValidateLmtPrdcont01Rule;
import com.irdstudio.efp.nls.service.common.rules.credit.CtrLoanIsActiveRule;
import com.irdstudio.efp.nls.service.common.rules.credit.HasCreditInfoRule;
import com.irdstudio.efp.nls.service.facade.NlsPublicService;
import com.irdstudio.efp.nls.service.facade.NlsQueueSoltComnService;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 需求编号:2019D08--
 * 问题编号:
 * 开发人员: caoxin
 * 创建日期:2019/12/12
 * 功能描述:
 * 修改日期:2019/12/12
 * 修改描述:
 */
@Service("psdLmtGenerateService")
public class PsdLmtGenerateService {
    private static Logger logger = LoggerFactory.getLogger(PsdLmtGenerateService.class);

    @Autowired
    private LmtRepository lmtRepository;
    @Autowired
    private NlsRepository nlsRepository;
    @Autowired
    private CtrLoanRepository ctrLoanRepository;
    @Autowired
    private CuratorLock curatorLock;
    private static final String PT_PRODUCT_USERS_LOCK = "/wd/psd/pt_product_user/";

    private static final long DEFAULT_EXPIRE_TIME = 3 * 60;

    private void activeLmtCommonCheck(NlsCreditInfoVO selectCreditInfo, LmtPrdContVO selectLmtPrdCont, CtrLoanContVO selectLoanCtr) throws BizException {
        NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
        nlsCreditInfoVO.checkFor(new HasCreditInfoRule(selectCreditInfo));
        nlsCreditInfoVO.checkFor(new ValidateLmtPrdcont01Rule(selectLmtPrdCont));
        nlsCreditInfoVO.checkFor(new CtrLoanIsActiveRule(selectLoanCtr.getContState()));
    }

    // 放款号和还款号为空的情况
    public void preProcessActiveLmt(PsdLimitActivatedReqBean psdLimitActivatedReqBean) throws BizException {
        NlsCreditInfoVO selectCreditInfo = nlsRepository.getNlsCreditInfoBySeq(psdLimitActivatedReqBean.getCrdtAppFlowNo());
        NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
        nlsCreditInfoVO.checkFor(new HasCreditInfoRule(selectCreditInfo));
        selectCreditInfo.setOperateAgency(psdLimitActivatedReqBean.getBrchCd());
        nlsCreditInfoService.updateByPk(selectCreditInfo);
        try {
            sendMsgToMq(selectCreditInfo, "2");
        } catch (UnsupportedEncodingException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e.getMessage());
            }
        }
    }

    // 额度激活,放款号和还款号不为空的情况
    public void processActiveLmt(PsdLimitActivatedReqBean psdLimitActivatedReqBean) throws BizException {
        try {

            NlsCreditInfoVO selectCreditInfo = nlsRepository.getNlsCreditInfoBySeq(psdLimitActivatedReqBean.getCrdtAppFlowNo());
            LmtPrdContVO selectLmtPrdCont = lmtRepository.getLmtPrdContBySeq(psdLimitActivatedReqBean.getCrdtAppFlowNo());
            CtrLoanContVO selectLoanCtr = ctrLoanRepository.getLmtPrdContBySeq(psdLimitActivatedReqBean.getCrdtAppFlowNo());
            activeLmtCommonCheck(selectCreditInfo, selectLmtPrdCont, selectLoanCtr);
            //更新授信信息表卡号信息
            ackAccountNumber(psdLimitActivatedReqBean, selectCreditInfo);
            //更新额度为有效
            activeLmt(selectLmtPrdCont, selectCreditInfo);
            //发送短信
            /*CusIndivVO inCusIndivVO = new CusIndivVO();
            inCusIndivVO.setCertCode(selectCreditInfo.getCertCode());
            CusIndivVO cusIndivVO = cusIndivService.queryByCondition(inCusIndivVO);
            String phone = cusIndivVO.getPhone();
            BigDecimal amount = selectLmtPrdCont.getLmtAmt().setScale(4, BigDecimal.ROUND_HALF_UP);
            DecimalFormat df = new DecimalFormat("###,###.00");
            String str = df.format(amount);
            nlsPublicService.sendLmtActivatedMessage(phone,str);*/
            selectCreditInfo.setNlsOperOrgid(psdLimitActivatedReqBean.getBrchCd());
            nlsCreditInfoService.updateByPk(selectCreditInfo);
            sendMsgToMq(selectCreditInfo, "3");

        } catch (BizException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e.getMessage());
            }
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), e.getMessage());
        } catch (UnsupportedEncodingException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e.getMessage());
            }
        } finally {
        }
    }

    private void ackAccountNumber(PsdLimitActivatedReqBean psdLimitActivatedReqBean, NlsCreditInfoVO selectCreditInfo) {
        selectCreditInfo.setRecvAccount(psdLimitActivatedReqBean.getDistrCardNo());
        selectCreditInfo.setDnAccount(psdLimitActivatedReqBean.getDistrCardNo());
        selectCreditInfo.setCusManager(selectCreditInfo.getNlsOperUserid());
        selectCreditInfo.setOperateAgency(psdLimitActivatedReqBean.getBrchCd());
        nlsCreditInfoService.updateByPk(selectCreditInfo);
    }



    private void sendMsgToMq(NlsCreditInfoVO selectCreditInfo, String sequnce) throws UnsupportedEncodingException {
        selectCreditInfo.setSoltStage(PrdAdaptedSoltEnums.PsdSoltStageEnum.LIMITACTIVE.getVALUE());
        producerService.sendMsg(new Message(TopicEnums.QUEUE_TASK_CREDIT_TOPIC.getTopicId(), TagEnums.TAG_QUEUE_CREDIT_TASK.getTagId(), selectCreditInfo.getLmtApplySeq() + "-" + sequnce,
                JSON.toJSONString(selectCreditInfo).getBytes("UTF-8")));
    }



    public PsdLimitActivatedRespBean getPsdLimitActivatedRespBean(PsdLimitActivatedReqBean psdLimitActivatedReqBean) {

        NlsCreditInfoVO selectCreditInfo = nlsRepository.getNlsCreditInfoBySeq(psdLimitActivatedReqBean.getCrdtAppFlowNo());
        PsdLimitActivatedRespBean psdLimitActivatedRespBean = new PsdLimitActivatedRespBean();
        psdLimitActivatedRespBean.setRetCd(EsbSysHeadEnums.RetStEnum.SUCCESS.getCode());
        psdLimitActivatedRespBean.setRetMsg(EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE());

        try {
            //目前渠道端没用到该字段，涉及新核心改造，注释然后返回
            //invokeAccountQuery(selectCreditInfo, psdLimitActivatedRespBean);
            psdLimitActivatedRespBean.setIAcctFlg("2");
        } catch (Exception e) {
            logger.error("普税贷额度激活查询账户信息失败", e.getMessage());
            psdLimitActivatedRespBean.setIAcctFlg("2");
        }
        try {
            invokeMobileBankQuery(selectCreditInfo, psdLimitActivatedRespBean);
        } catch (Exception e) {
            logger.error("普税贷额度激活查询手机银行信息失败", e.getMessage());
            psdLimitActivatedRespBean.setWhthrOpnMblBnk("2");
        }
        try {
            invokeNetworkBankQuery(selectCreditInfo, psdLimitActivatedRespBean);
        } catch (Exception e) {
            logger.error("普税贷额度激活查询网上银行信息失败", e.getMessage());
            psdLimitActivatedRespBean.setWhthrOpnEbnk("2");
        }

        return psdLimitActivatedRespBean;
    }

    private void invokeNetworkBankQuery(NlsCreditInfoVO selectCreditInfo, PsdLimitActivatedRespBean psdLimitActivatedRespBean) throws Exception {
        NetworkBankInfoRespBean resp = null;
        NetworkBankInfoReqBean res = new NetworkBankInfoReqBean();
        res.setGlobaNo(selectCreditInfo.getGlobalSerno());
        res.setIdentTp(selectCreditInfo.getCertType());
        res.setIdentNo(selectCreditInfo.getCertCode());
        res.setOprtBrchNo(selectCreditInfo.getNlsOperOrgid());
        resp = networkBankInfoService.applyNetworkBankInfo(res);
        /*
        EsbInvokeWrapper esbInvokeWrapper = new EsbInvokeWrapper(networkBankInfoService, res, nlsQueueSoltComnService);
        resp = (NetworkBankInfoRespBean) esbInvokeWrapper.invoke3Threes();*/
        if (Objects.isNull(resp)) {
            psdLimitActivatedRespBean.setWhthrOpnEbnk("0");
        }
        psdLimitActivatedRespBean.setWhthrOpnEbnk(StringUtils.isNotEmpty(resp.getEbnkCustNo()) ? "1" : "0");

    }

    private void invokeMobileBankQuery(NlsCreditInfoVO selectCreditInfo, PsdLimitActivatedRespBean psdLimitActivatedRespBean) throws Exception {
        MobileBankInfoRespBean resp = null;
        MobileBankInfoReqBean res = new MobileBankInfoReqBean();
        res.setGlobaNo(selectCreditInfo.getGlobalSerno());
        res.setIdentTp(selectCreditInfo.getCertType());//操作类型身份证
        res.setOprtTp("1");// 证件号码
        res.setOprtChanFlg("07");//操作渠道代码：网络信贷系统
        res.setIdentTp(selectCreditInfo.getCertType());
        res.setIdentNo(selectCreditInfo.getCertCode());
        resp = mobileBankInfoService.applyMobileBankInfo(res);
        /*EsbInvokeWrapper esbInvokeWrapper = new EsbInvokeWrapper(mobileBankInfoService, res, nlsQueueSoltComnService);
        resp = (MobileBankInfoRespBean) esbInvokeWrapper();*/
        if (Objects.isNull(resp)) {
            psdLimitActivatedRespBean.setWhthrOpnMblBnk("0");
        }
        psdLimitActivatedRespBean.setWhthrOpnMblBnk(StringUtils.isNotEmpty(resp.getMblBnkCustNo()) ? "1" : "0");
    }

    private void invokeAccountQuery(NlsCreditInfoVO selectCreditInfo, PsdLimitActivatedRespBean psdLimitActivatedRespBean) throws ESBException, InterruptedException {
        AccountQueryRespBean accountQueryRespBean = null;
        AccountQueryReqBean accountQueryReqBean = new AccountQueryReqBean();
        accountQueryReqBean.setAcctNo(selectCreditInfo.getRecvAccount());
        accountQueryReqBean.setAcctCurrCd("156");
        accountQueryReqBean.setStoreTrm("000");
        accountQueryReqBean.setPgTrnOnceDsplNum("10");
        accountQueryReqBean.setPgTrnBegPosn("1");
//        accountQueryReqBean.setGlobaNo(selectCreditInfo.getGlobalSerno());
        EsbInvokeWrapper esbInvokeWrapper = new EsbInvokeWrapper(accountQueryService, accountQueryReqBean, nlsQueueSoltComnService);
        accountQueryRespBean = (AccountQueryRespBean) esbInvokeWrapper.invoke3Threes();
        if (Objects.isNull(accountQueryReqBean)) {
            psdLimitActivatedRespBean.setIAcctFlg("0");
        }
        psdLimitActivatedRespBean.setIAcctFlg("1".equals(accountQueryRespBean.getAcctLvl()) ? "1" : "0");

    }


    private void activeLmt(LmtPrdContVO lmtPrdCont, NlsCreditInfoVO nlsCreditInfoVO) throws BizException {
        lmtPrdCont.setLmtStatus(ConsoleConstant.LIMIT_STS_02);
        lmtPrdCont.setCusId(nlsCreditInfoVO.getCusId());
        String openday = pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001);
        // 签订日期
        lmtPrdCont.setSignDate(openday);
        lmtPrdCont.setLoanAccount(nlsCreditInfoVO.getDnAccount());
        lmtPrdCont.setRecvAccount(nlsCreditInfoVO.getRecvAccount());
        int result = lmtPrdContService.updateByPk(lmtPrdCont);
        if (result != 1) {
            logger.error("普税贷额度激活失败 更新额度信息失败！");
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "普税贷额度激活失败 更新额度信息失败");
        }
    }


    @Autowired
    @Qualifier("lmtPrdContService")
    private LmtPrdContService lmtPrdContService;

    @Autowired
    @Qualifier("producerService")
    private MQProducerMessageClient producerService;

    @Autowired
    @Qualifier("accountQueryService")
    private AccountQueryService accountQueryService;

    @Autowired
    @Qualifier("nlsQueueSoltComnService")
    private NlsQueueSoltComnService nlsQueueSoltComnService;

    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;

    @Autowired
    @Qualifier("networkBankInfoService")
    private NetworkBankInfoService networkBankInfoService;

    @Autowired
    @Qualifier("mobileBankInfoService")
    private MobileBankInfoService mobileBankInfoService;

    @Autowired
    @Qualifier("pubSysInfoService")
    private PubSysInfoService pubSysInfoService;

    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;

    @Autowired
    @Qualifier("nlsPublicService")
    private NlsPublicService nlsPublicService;
}
